import asyncpg
from motor.motor_asyncio import AsyncIOMotorClient
from typing import Optional
import redis.asyncio as redis
from app.core.config import settings
import logging

logger = logging.getLogger(__name__)

class Database:
    pg_pool: Optional[asyncpg.Pool] = None
    mongo_client: Optional[AsyncIOMotorClient] = None
    mongo_db = None
    redis_client: Optional[redis.Redis] = None
    
    @classmethod
    async def connect(cls):
        try:
            cls.pg_pool = await asyncpg.create_pool(
                settings.database_url,
                min_size=settings.db_pool_min_size,
                max_size=settings.db_pool_max_size,
                command_timeout=60
            )
            logger.info("PostgreSQL connection pool created")
            
            cls.mongo_client = AsyncIOMotorClient(
                settings.mongodb_url,
                maxPoolSize=settings.mongodb_max_pool_size
            )
            cls.mongo_db = cls.mongo_client.chatbot_db
            logger.info("MongoDB connection established")
            
            if settings.redis_url:
                cls.redis_client = await redis.from_url(
                    settings.redis_url,
                    encoding="utf-8",
                    decode_responses=True
                )
                logger.info("Redis connection established")
                
        except Exception as e:
            logger.error(f"Database connection failed: {e}")
            raise
    
    @classmethod
    async def disconnect(cls):
        if cls.pg_pool:
            await cls.pg_pool.close()
            logger.info("PostgreSQL connection pool closed")
            
        if cls.mongo_client:
            cls.mongo_client.close()
            logger.info("MongoDB connection closed")
            
        if cls.redis_client:
            await cls.redis_client.close()
            logger.info("Redis connection closed")
    
    @classmethod
    async def get_pg_connection(cls):
        return cls.pg_pool.acquire()
    
    @classmethod
    def get_mongo_db(cls):
        return cls.mongo_db
    
    @classmethod
    def get_redis_client(cls):
        return cls.redis_client

db = Database()